#include "config.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>

#include "can_uim.h"
#include <sys/ipc.h>
#include <sys/msg.h>
#include "common.h"
#include "msg_def.h"
#include <unistd.h>
#include <semaphore.h>
#include <sys/time.h>
#include "board_data_proc.h"
#include "rs485.h"
#include "sharemem.h"

#include <pthread.h>



extern CUim_MainCtl  * g_uimCanHandle; 
extern CCan * g_subBoardCanHandle;


#ifdef _x86_64
const char * configFiles[MAX_CONFIG_FILE_NUM] = 
{
    "/home/hcgy/Documents/esm6800h/test/xml_test/openlid.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/closelid.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/xr.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/bath.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/trans.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/dp8.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/heat_seal.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/dj.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/bath.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/dp8suck.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/dp8tip.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/dp8spit.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/dp8tip.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/xr.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/bath.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/djclean.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/djaddsample.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/translid.xml",
    "/home/hcgy/Documents/esm6800h/test/xml_test/dp8suck_ab.xml",
};
#else
const char * configFiles[MAX_CONFIG_FILE_NUM] = 
{
    "/mnt/nandflash/apps/config/openlid.xml",
    "/mnt/nandflash/apps/config/closelid.xml",
    "/mnt/nandflash/apps/config/xr.xml",
    "/mnt/nandflash/apps/config/bath.xml",
    "/mnt/nandflash/apps/config/trans.xml",
    "/mnt/nandflash/apps/config/dp8.xml",
    "/mnt/nandflash/apps/config/heat_seal.xml",
    "/mnt/nandflash/apps/config/dj.xml",
    "/mnt/nandflash/apps/config/bath.xml",
    "/mnt/nandflash/apps/config/dp8suck.xml",
    "/mnt/nandflash/apps/config/dp8tip.xml",
    "/mnt/nandflash/apps/config/dp8spit.xml",
    "/mnt/nandflash/apps/config/dp8tip.xml",
    "/mnt/nandflash/apps/config/xr.xml",
    "/mnt/nandflash/apps/config/bath.xml",
    "/mnt/nandflash/apps/config/djclean.xml",    
    "/mnt/nandflash/apps/config/djaddsample.xml",
    "/mnt/nandflash/apps/config/translid.xml",
    "/mnt/nandflash/apps/config/dp8suck_ab.xml",
};
#endif

pthread_mutex_t mutex_read_param = PTHREAD_MUTEX_INITIALIZER;

xmlXPathObjectPtr getNodeset(xmlDocPtr pdoc, const xmlChar *xpath)
{
    xmlXPathContextPtr context = NULL; //定义XPath上下文指针
    context = xmlXPathNewContext(pdoc);//用xml文档指针来初始化context指针
    xmlXPathObjectPtr result = NULL; //定义XPath结果指针

    if (pdoc == NULL)
    {
        printf("pdoc is NULL\n");
        return NULL;
    }

    if (xpath)
    {
        if (context == NULL)
        {
            printf("context is NULL\n");
            return NULL;
        }

        result = xmlXPathEvalExpression(xpath, context);//计算xpath的查询结果，并存入result中
        xmlXPathFreeContext(context); 
        if (result == NULL)
        {
            printf("xmlXPathEvalExpression return NULL\n");
            return NULL;
        }


        if (xmlXPathNodeSetIsEmpty(result->nodesetval))
        //使用result->nodesetval得到节点集合指针，其中包含了所有符合Xpath查询结果的节点
        {
            xmlXPathFreeObject(result);//使用释放Xpath对象指针；
            printf("nodeset is empty\n");
            return NULL;
        }
    }

    return result;
}

int getEleCtlIdByString(const char * eleCtlName)
{
#ifndef _QPCR
    if(strcmp(eleCtlName,"openlid_y") == 0)
    {
        return 11;
    }

    if(strcmp(eleCtlName,"openlid_z") == 0)
    {
        return 10;
    }

    if(strcmp(eleCtlName,"openlid_jaw") == 0)
    {
#ifdef _GP_1
        return 83;
#else
        return 81;  
#endif
    }

    if(strcmp(eleCtlName,"scancode") == 0)
    {
        return 12;
    }

    if(strcmp(eleCtlName,"xr_y") == 0)
    {
        return 16;
    }

    if(strcmp(eleCtlName,"xr_z") == 0)
    {
        return 19;
    }

    if(strcmp(eleCtlName,"xr_jaw") == 0)
    {
        return 18;
    }

    if(strcmp(eleCtlName,"xr_r") == 0)
    {
        return 17;
    }

    if(strcmp(eleCtlName,"dp8_x") == 0)
    {
#ifdef _GP_1
        return 81;
#else
        return 82;  
#endif        
    }

    if(strcmp(eleCtlName,"dp8_y") == 0)
    {
#ifdef _GP_1
        return 80;
#else
        return 83; 
#endif
        
    }

    if(strcmp(eleCtlName,"dp8_z") == 0)
    {
        return 15;
    }

    if(strcmp(eleCtlName,"dp8_suck") == 0)
    {
        return 14;
    }

    if(strcmp(eleCtlName,"heat_z") == 0)
    {
        return 13;
    }
    
    if(strcmp(eleCtlName,"jaw_z") == 0)
    {
        return 22;
    }
    
    if(strcmp(eleCtlName,"dp1_jaw") == 0)
    {
#ifdef _GP_1
        return 82;
#else
        return 80; 
#endif
        //return 105;
    }

    if(strcmp(eleCtlName,"dp1_x") == 0)
    {
        return 20;
    }

    if(strcmp(eleCtlName,"dp1_y") == 0)
    {
        return 21;
    }
#else

    if(strcmp(eleCtlName,"bash_zl") == 0)
    {
        return 45;
    }

    if(strcmp(eleCtlName,"bash_zr") == 0)
    {
        return 46;
    }

    if(strcmp(eleCtlName,"logistics_y") == 0)
    {
        return 44;
    }

    if(strcmp(eleCtlName,"logistics_z") == 0)
    {
        return 43;
    }

    if(strcmp(eleCtlName,"logistics_jaw") == 0)
    {
        return 42;
    }

    if(strcmp(eleCtlName,"logistics_x") == 0)
    {
        return 41;
    }

    if(strcmp(eleCtlName,"bath_x") == 0)
    {
        return 48;
    }

    if(strcmp(eleCtlName,"dj_x") == 0)
    {
        return 49;
    }

    if(strcmp(eleCtlName,"dj_y") == 0)
    {
        return 50;
    }

    if(strcmp(eleCtlName,"dj_z") == 0)
    {
        return 51;
    }

    if(strcmp(eleCtlName,"dj_pump") == 0)
    {
        return 40;
    }

    if(strcmp(eleCtlName,"dj_outcleanpump") == 0)
    {
        return 84;
    }

    if(strcmp(eleCtlName,"dj_incleanpump") == 0)
    {
        return 85;
    }

    if(strcmp(eleCtlName,"dj_incleanvalve") == 0)
    {
        return 86;
    }

    if(strcmp(eleCtlName,"dj_wasteliquidpump") == 0)
    {
        return 87;
    }
#endif
    return 0;
}


int modify_param_xml(int fileId,const char* pathInXml,void * paramIn)
{

    xmlDocPtr pdoc = NULL; 

    xmlNodePtr proot = NULL;

    pdoc = xmlReadFile(configFiles[fileId],"UTF-8",0);//

    proot = xmlDocGetRootElement(pdoc);

    if (proot == NULL) 
    {
        printf("error: file is empty!\n");
        return 1;
    }

    xmlChar *xpath = BAD_CAST (pathInXml);

    xmlXPathObjectPtr result = getNodeset(pdoc, xpath);

    if (result == NULL)
    {
        printf("result is NULL\n");
        exit(1);
    }

    xmlNodeSetPtr nodeset = result->nodesetval;

    xmlNodePtr eleCtlNode = nodeset->nodeTab[0];


    move_param * pstMoveParam = (move_param *)paramIn;
    xmlNodePtr pnode=NULL;
    while (eleCtlNode != NULL)
    {
        if(xmlStrcmp(eleCtlNode->name, BAD_CAST ("electl")))
        {
            eleCtlNode = eleCtlNode->next;
            continue;
        }
        pnode = xmlFirstElementChild(eleCtlNode);
        int modifyFlag = 0;
        while(pnode!=NULL)
        {
            //printf("    child node name:%s\n",pnode->name);
            if (!xmlStrcmp(pnode->name, BAD_CAST ("ele")))//xmlStrcmp为对比，相同时返回值为0
            {
                //printf("write: %s\n",
                //        ((char*) xmlNodeGetContent(cur)));//xmlNodeGetContent为获得某结点的内容
                
                int sid = getEleCtlIdByString((char*) xmlNodeGetContent(pnode));
                //printf("sid from xml:%d, sid in param:%d\n",sid,pstCtlUim->sid);
                if(sid==pstMoveParam->sid)
                {
                    char strBuff[64];
                    memset(strBuff,0,64);
                    xmlNodePtr targetNode = xmlFirstElementChild(eleCtlNode);
                    while(targetNode!=NULL)
                    {
                        if (!xmlStrcmp(targetNode->name, BAD_CAST ("speed")))//xmlStrcmp为对比，相同时返回值为0
                        {
                            sprintf(strBuff,"%d",pstMoveParam->speed);
                            xmlNodeSetContent(targetNode,(xmlChar*)strBuff);
                        }
                        else if (!xmlStrcmp(targetNode->name, BAD_CAST ("acc")))//xmlStrcmp为对比，相同时返回值为0
                        {
                            sprintf(strBuff,"%d",pstMoveParam->inc_speed);
                            xmlNodeSetContent(targetNode,(xmlChar*)strBuff);
                        }
                        else if (!xmlStrcmp(targetNode->name, BAD_CAST ("dec")))//xmlStrcmp为对比，相同时返回值为0
                        {
                            sprintf(strBuff,"%d",pstMoveParam->dec_speed);
                            xmlNodeSetContent(targetNode,(xmlChar*)strBuff);
                        }
                        else if (!xmlStrcmp(targetNode->name, BAD_CAST ("position")))//xmlStrcmp为对比，相同时返回值为0
                        {
                            sprintf(strBuff,"%d",pstMoveParam->pos);
                            xmlNodeSetContent(targetNode,(xmlChar*)strBuff);
                        }                        

                        targetNode = xmlNextElementSibling(targetNode);
                    }
                    modifyFlag = 1;    
                }
                break;                //printf("elename:%s, sid:%d\n",(char*) xmlNodeGetContent(pnode),ptrParamEleCtl->sid);
                
            }
            pnode = xmlNextElementSibling(pnode);            
        }
        if(modifyFlag==1)
        {
            break;
        }
        eleCtlNode = eleCtlNode->next;
    }

    //write to xml;
    
    //xmlSaveFile("testXmlWrite.xml",pdoc);

    xmlSaveFormatFile(configFiles[fileId],pdoc,1);

    xmlXPathFreeObject(result);
    xmlFreeDoc(pdoc);

    xmlCleanupParser();
    xmlMemoryDump();
}

int modify_djreagent_xml(const void * paramIn)
{
    dj_reagent * ptrParam = (dj_reagent *)paramIn;
    xmlDocPtr pdoc = NULL; 

    xmlNodePtr proot = NULL;

    const int SID_DJ_PUMP = 40;

    pdoc = xmlReadFile(configFiles[I_MODULE_DJREAGENT],"UTF-8",0);//

    proot = xmlDocGetRootElement(pdoc);

    if (proot == NULL) 
    {
        printf("error: file is empty!\n");
        return 1;
    }

    const char * pathArr[3] = {
        "/dj/suck_air/electl",
        "/dj/suck_reagent/electl",
        "/dj/spit_reagent/electl",
    };

    int coeff = 64;//32000/500
    int positionArr[3] = {coeff*ptrParam->quantity_air,
                          coeff*ptrParam->quantity_suck,
                          coeff*ptrParam->quantity_spit};
    
    for(int indexPath = 0; indexPath<3; indexPath++)
    {
        xmlChar *xpath = BAD_CAST (pathArr[indexPath]);

        xmlXPathObjectPtr result = getNodeset(pdoc, xpath);

        if (result == NULL)
        {
            printf("result is NULL\n");
            continue;
        }

        xmlNodeSetPtr nodeset = result->nodesetval;

        xmlNodePtr eleCtlNode = nodeset->nodeTab[0];


        //move_param * pstMoveParam = (move_param *)paramIn;
        xmlNodePtr pnode=NULL;
        xmlChar * ptrNodeContent = NULL;
        while (eleCtlNode != NULL)
        {
            if(xmlStrcmp(eleCtlNode->name, BAD_CAST ("electl")))
            {
                eleCtlNode = eleCtlNode->next;
                continue;
            }
            pnode = xmlFirstElementChild(eleCtlNode);
            int modifyFlag = 0;
            while(pnode!=NULL)
            {
                //printf("    child node name:%s\n",pnode->name);
                if (!xmlStrcmp(pnode->name, BAD_CAST ("ele")))//xmlStrcmp为对比，相同时返回值为0
                {
                    //printf("write: %s\n",
                    //        ((char*) xmlNodeGetContent(cur)));//xmlNodeGetContent为获得某结点的内容
                    int sid = 0;
                    ptrNodeContent = xmlNodeGetContent(pnode);
                    if(ptrNodeContent)
                    {
                        sid = getEleCtlIdByString((char*) ptrNodeContent);
                        xmlFree(ptrNodeContent);
                    }
                    
                    //printf("sid from xml:%d, sid in param:%d\n",sid,pstCtlUim->sid);
                    if(sid==SID_DJ_PUMP)
                    {
                        char strBuff[64];
                        memset(strBuff,0,64);
                        xmlNodePtr targetNode = xmlFirstElementChild(eleCtlNode);
                        while(targetNode!=NULL)
                        {
                            if (!xmlStrcmp(targetNode->name, BAD_CAST ("position")))//xmlStrcmp为对比，相同时返回值为0
                            {
                                sprintf(strBuff,"%d",positionArr[indexPath]);
                                printf("set position to %d\n",positionArr[indexPath]);
                                xmlNodeSetContent(targetNode,(xmlChar*)strBuff);
                            }                        

                            targetNode = xmlNextElementSibling(targetNode);
                        }
                        modifyFlag = 1;    
                    }
                    break;                //printf("elename:%s, sid:%d\n",(char*) xmlNodeGetContent(pnode),ptrParamEleCtl->sid);
                    
                }
                pnode = xmlNextElementSibling(pnode);            
            }
            if(modifyFlag==1)
            {
                break;
            }
            eleCtlNode = eleCtlNode->next;
        }
        xmlXPathFreeObject(result);
    }   

    //write to xml;
    
    //xmlSaveFile("testXmlWrite.xml",pdoc);

    xmlSaveFormatFile(configFiles[I_MODULE_DJREAGENT],pdoc,1);    
    xmlFreeDoc(pdoc);
    xmlCleanupParser();
    xmlMemoryDump();
    return 0;
}

int read_param_xml(int fileId,const char* pathInXml,void * paramOut)
{
    xmlDocPtr pdoc = NULL; 

    xmlNodePtr proot = NULL;

    pdoc = xmlReadFile(configFiles[fileId],"UTF-8",0);//xmlParseFile(fileNameIn);

    proot = xmlDocGetRootElement(pdoc);

    if (proot == NULL) 
    {
        printf("error: file is empty!\n");
        xmlFreeDoc(pdoc);
        return 1;
    }

    xmlChar *xpath = BAD_CAST (pathInXml);

    xmlXPathObjectPtr result = getNodeset(pdoc, xpath);

    if (result == NULL)
    {
        printf("result is NULL\n");
        xmlFreeDoc(pdoc);
        exit(1);
    }

    //printf("getNodeSet finished\n");
    
    paramProcNode * ptrProcParam = (paramProcNode *)paramOut;
    int * tempPtr = (int*)paramOut;
    paramEleCtl * ptrParamEleCtl = (paramEleCtl *) (tempPtr+1);

    xmlNodePtr pnode=NULL;

    if (result)
    {
        xmlNodeSetPtr nodeset = result->nodesetval; //获取查询到的节点指针集合，其中包含了所有符合Xpath查询结果的节点；
        xmlNodePtr cur;//声明一个临时的当前结点指针

        //nodeset->nodeNr是集合元素总数,for遍历每个符合结果的结点
        //int i = 0;
        ptrProcParam->numEleCtl = nodeset->nodeNr;
        //printf("num nodes found:%d\n",ptrProcParam->numEleCtl);
        //for (i = 0; i < nodeset->nodeNr; i++)
        //{
            cur = nodeset->nodeTab[0];//遍历
            //printf("node name:%s,addr:%p\n",cur->name,ptrParamEleCtl);
/**************接下来就是使用libxml2函数进行结点的操作**********/
            while (cur != NULL)
            {
             //查找名为write的结点，并输出其内容
                //printf("node name:%s\n",cur->name);
                if(xmlStrcmp(cur->name, BAD_CAST ("electl")))
                {
                    cur = cur->next;
                    continue;
                }
                pnode = xmlFirstElementChild(cur);
                while(pnode!=NULL)
                {
                    //printf("    child node name:%s\n",pnode->name);
                    xmlChar * ptrContent = NULL;
                    if (!xmlStrcmp(pnode->name, BAD_CAST ("ele")))//xmlStrcmp为对比，相同时返回值为0
                    {
                        //printf("write: %s\n",
                        //        ((char*) xmlNodeGetContent(cur)));//xmlNodeGetContent为获得某结点的内容
                        ptrContent = xmlNodeGetContent(pnode);
                        if(ptrContent)
                        {
                            ptrParamEleCtl->sid = getEleCtlIdByString((char*) ptrContent);
                            xmlFree(ptrContent);
                        }
                        //printf("elename:%s, sid:%d\n",(char*) xmlNodeGetContent(pnode),ptrParamEleCtl->sid);
                        pnode = xmlNextElementSibling(pnode);
                        continue;
                    }

                    if (!xmlStrcmp(pnode->name, BAD_CAST ("speed")))//xmlStrcmp为对比，相同时返回值为0
                    {
                        ptrContent = xmlNodeGetContent(pnode);
                        if(ptrContent)
                        {
                            ptrParamEleCtl->speed = atoi((char*) ptrContent);
                            xmlFree(ptrContent);
                        }                        
                        pnode = xmlNextElementSibling(pnode);
                        continue;
                        //printf("set speed to %d\n",ptrParamEleCtl->speed);
                    }

                    if (!xmlStrcmp(pnode->name, BAD_CAST ("acc")))//xmlStrcmp为对比，相同时返回值为0
                    {       
                        
                        ptrContent = xmlNodeGetContent(pnode);
                        if(ptrContent)
                        {
                            ptrParamEleCtl->acc = atoi((char*) ptrContent);
                            xmlFree(ptrContent);
                        }
                        pnode = xmlNextElementSibling(pnode);
                        continue;
                    }

                    if (!xmlStrcmp(pnode->name, BAD_CAST ("dec")))//xmlStrcmp为对比，相同时返回值为0
                    {
                        
                        ptrContent = xmlNodeGetContent(pnode);
                        if(ptrContent)
                        {
                            ptrParamEleCtl->dec = atoi((char*) ptrContent);
                            xmlFree(ptrContent);
                        }                       
                        
                        pnode = xmlNextElementSibling(pnode);
                        continue;
                    }

                    if (!xmlStrcmp(pnode->name, BAD_CAST ("position")))//xmlStrcmp为对比，相同时返回值为0
                    {                       
                        
                        ptrContent = xmlNodeGetContent(pnode);
                        if(ptrContent)
                        {
                            ptrParamEleCtl->position = atoi((char*) ptrContent);
                            xmlFree(ptrContent);
                        }
                        pnode = xmlNextElementSibling(pnode);
                        continue;
                    }

                    if (!xmlStrcmp(pnode->name, BAD_CAST ("pre_wait")))//xmlStrcmp为对比，相同时返回值为0
                    {                        
                        
                        ptrContent = xmlNodeGetContent(pnode);
                        if(ptrContent)
                        {
                            ptrParamEleCtl->preWait = atoi((char*) ptrContent);
                            xmlFree(ptrContent);
                        }
                        pnode = xmlNextElementSibling(pnode);
                        continue;
                    }

                    pnode = xmlNextElementSibling(pnode);
                    
                }
                
                // //创建结点，结点名称为CHILD
                // xmlNodePtr child=xmlNewNode(NULL,BAD_CAST"CHILD");
                // //设置其内容和属性
                // xmlNodeSetContent(child,BAD_CAST"子节点");
                // xmlSetProp(child,BAD_CAST"属性名"，BAD_CAST"属性内容");
                // //移除属性,返回0成功，-1失败，每次只能移除一个属性
                // int i;
                // i=xmlRemoveProp(cur);
                // //将child添加给cur为子结点
                // xmlAddChild(cur,child);

                // //创建并直接添加子节点
                //  xmlNewTextChild(cur, NULL, BAD_CAST "结点名称", BAD_CAST "结点内容");
                // //删除newNode1
                //   if (!xmlStrcmp(cur->name, BAD_CAST "newGrandSon"))
                //        {
                //             xmlNodePtr tempNode;
                //            tempNode = cur->next; //使用一个临时变量来存储断链节点的后续节点
                //            xmlUnlinkNode(cur); //将当前节点从文档中断链（unlink），这样本文档就不会再包含这个子节点
                //            xmlFreeNode(cur); //手动删除断链节点的内存
                //            cur = tempNode;
                //           continue;
                //       }
                //printf("ptrParamEleCtl added\n");
                cur = cur->next;
                
                ptrParamEleCtl++;
            }
        //}

        xmlXPathFreeObject(result); //释放结果指针
    }

    xmlFreeDoc(pdoc);
    xmlCleanupParser();
    xmlMemoryDump();

}

int convertEleCtlId(int sidIn)
{
    int sidOut = 0;
    if(sidIn>=10 && sidIn<=(MAX_UIM_CTL_NUM + 10))
    {
        sidOut = sidIn-10;
    }
    else if(sidIn>=40 && sidIn<=(MAX_UIM_CTL_NUM_PCR + 40))
    {
        sidOut = sidIn-40;
    }
    else if(sidIn>=80 && sidIn<=89)
    {
        sidOut = sidIn-55;
    }
    else if(sidIn>=100 && sidIn<=105)
    {
        //for wantec ele ctroller.
        sidOut = sidIn - 70;
    }

    return sidOut;
}

int main(int argc, char * argv[])
{
    char * memBuff = new char[1024];
    memset(memBuff,0,1024);
    read_param_xml(I_FILE_OPENLID,"/openlid/goto_open/electl",memBuff);

    int * ptrNum =  (int *)memBuff;

    printf("num of param:%d\n",*ptrNum);
    
    int num = * ptrNum;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    for(int i=0;i<num;i++)
    {
        printf("\n-------\nsid:%d\nposition:%d\nspeed:%d\nacc:%d\ndec:%d\n",
        ptrParamEleCtl->sid,
        ptrParamEleCtl->position,
        ptrParamEleCtl->speed,
        ptrParamEleCtl->acc,
        ptrParamEleCtl->dec);

        ptrParamEleCtl++;
    }

    delete [] memBuff;

    return 0;
}

void openlid_gotoscan_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param); 
    read_param_xml(I_FILE_OPENLID,"/openlid/gotoscan/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

int openlid_gotoscan_act(void * dataIn)
{
    int * ptrNum =  (int *)dataIn;

    printf("enter in openlid_gotoscan_act\n");
    
    int num = * ptrNum;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    move_param  stMoveParam;
    memset(&stMoveParam,0,sizeof(move_param));

    printf("data read from xml,sid:%d,pos:%d,acc:%d,dec:%d,speed:%d\n",
    ptrParamEleCtl->sid,
    ptrParamEleCtl->position,
    ptrParamEleCtl->dec,
    ptrParamEleCtl->acc,
    ptrParamEleCtl->speed);
    stMoveParam.sid = ptrParamEleCtl->sid;
    stMoveParam.pos = ptrParamEleCtl->position;
    stMoveParam.dec_speed = ptrParamEleCtl->dec;
    stMoveParam.inc_speed = ptrParamEleCtl->acc;
    stMoveParam.speed = ptrParamEleCtl->speed;
    
    if(g_uimCanHandle)
    {
        if(ptrParamEleCtl->position == 0)
        {
           g_uimCanHandle->uim_ret_back(&stMoveParam);
        }
        else
        {
           g_uimCanHandle->uim_move(&stMoveParam);
        }

    }
    
    
    

    return 0;
    //sendMsgToAct(ptrParamEleCtl,QUEUE_MSG_TYPE_UIM, ptrParamEleCtl->sid,0);    
}

int openlid_gotoscan_update(void * dataIn,void * stdData)
{
    recvDataEleCtl * ptrData = (recvDataEleCtl *)dataIn;

    int * ptrFlagIn =  (int *)stdData;

    printf("in openlid_gotoscan_update,sid:%d,frameType:%d\n",ptrData->sid,ptrData->frameType);

    if(*ptrFlagIn==1)
    {
        return 1;
    }

    if(ptrData->sid == 11 && ptrData->frameType)
    {
        *ptrFlagIn = 1;
        return 1;
    }

    return 0;
}

void openlid_gotoscan_query(void * dataIn)
{
    // query_param queryParam;
    // memset(&queryParam,0,sizeof(query_param));
    // queryParam.queryCode = POS;
    // queryParam.sid = 11;
    // g_uimCanHandle->uim_query(&queryParam);
}


void openlid_scan_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_OPENLID,"/openlid/scan/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

int openlid_scan_act(void * dataIn)
{
    int ret = openlid_gotoscan_act(dataIn);

    return ret;
    //sendMsgToAct(ptrParamEleCtl,QUEUE_MSG_TYPE_UIM, ptrParamEleCtl->sid,0);    
}

int openlid_scan_update(void * dataIn,void * stdData)
{
    recvDataEleCtl * ptrData = (recvDataEleCtl *)dataIn;

    int * ptrFlagIn =  (int *)stdData;

    if(*ptrFlagIn==1)
    {
        return 1;
    }

    if(ptrData->sid == 12 && ptrData->frameType)
    {
        *ptrFlagIn = 1;
        return 1;
    }

    return 0;
}

void openlid_scan_query(void * dataIn)
{
    // query_param queryParam;
    // memset(&queryParam,0,sizeof(query_param));
    // queryParam.queryCode = POS;
    // queryParam.sid = 11;
    // g_uimCanHandle->uim_query(&queryParam);
}

int  sendMsgToAct(const  paramEleCtl * ptrParamEleCtl,int msgType,
     unsigned char sidIn,unsigned char indexOnBoard)
{
    msg_ctl_uim msgFrame;
    int ret = 0;
    memset(&msgFrame,0,sizeof(msg_ctl_uim));
    msgFrame.ctlFrame.un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
    msgFrame.ctlFrame.sid = sidIn;
    msgFrame.ctlFrame.opcode = MOVE;
    msgFrame.ctlFrame.un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
    msgFrame.ctlFrame.un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
    msgFrame.ctlFrame.un_cmd.moveCtl.position = ptrParamEleCtl->position;
    msgFrame.ctlFrame.un_cmd.moveCtl.ele_index = indexOnBoard;

    msgFrame.type = msgType;

    if(msgsnd(g_msg_id, (void*)&msgFrame, sizeof(ctl_uim), 0) < 0)
    {
        printf("msg send failed\n");
        ret = 1;
    }
    else
    {
        /* code */
        printf("msg send success,type is %d,opcode[%d]\n",msgFrame.type,msgFrame.ctlFrame.opcode);
        ret = 0;
    }
    return ret;
}


void configOpenlid(void * procIn)
{
    //int numProc = 1;
    //procNode * procArr = new procNode[numProc];


}

void openlid_gotoopen_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_OPENLID,"/openlid/goto_open/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

int openlid_gotoopen_act(void * dataIn)
{
    //openlid_gotoscan_act(dataIn);
    int * ptrNum =  (int *)dataIn;

    printf("enter in openlid_gotoopen_act\n");
    
    int num = * ptrNum;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    move_param  stMoveParam;
    memset(&stMoveParam,0,sizeof(move_param));

    printf("data read from xml,sid:%d,pos:%d,acc:%d,dec:%d,speed:%d\n",
    ptrParamEleCtl->sid,
    ptrParamEleCtl->position,
    ptrParamEleCtl->dec,
    ptrParamEleCtl->acc,
    ptrParamEleCtl->speed);
    stMoveParam.sid = ptrParamEleCtl->sid;
    stMoveParam.pos = ptrParamEleCtl->position;
    stMoveParam.dec_speed = ptrParamEleCtl->dec;
    stMoveParam.inc_speed = ptrParamEleCtl->acc;
    stMoveParam.speed = ptrParamEleCtl->speed;

    g_uimCanHandle->uim_move(&stMoveParam);
    
    ptrParamEleCtl++;

    ctl_uim ctlFrame;
    ctlFrame.opcode = MOVE;
    ctlFrame.sid = 1;
#ifdef _GP_1
    ctlFrame.un_cmd.moveCtl.ele_index = 3;
#else
    ctlFrame.un_cmd.moveCtl.ele_index = 1;
#endif
    ctlFrame.un_cmd.moveCtl.position = ptrParamEleCtl->position;
    ctlFrame.un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
    ctlFrame.un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
    ctlFrame.un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
    g_subBoardCanHandle->cmdAct(&ctlFrame);
    return 0;
    //sendMsgToAct(ptrParamEleCtl,QUEUE_MSG_TYPE_UIM, ptrParamEleCtl->sid,0);    
}

int openlid_gotoopen_update(void * dataIn,void * stdData)
{
    recvDataEleCtl * ptrData = (recvDataEleCtl *)dataIn;

    int * ptrFlagIn =  (int *)stdData;

    if(*ptrFlagIn==1)
    {
        return 1;
    }

    if(ptrData->sid == 11 && ptrData->frameType)
    {
        *ptrFlagIn = 1;
        return 1;
    }

    return 0;
}

void openlid_gotoopen_query(void * dataIn)
{
    // query_param queryParam;
    // memset(&queryParam,0,sizeof(query_param));
    // queryParam.queryCode = POS;
    // queryParam.sid = 11;
    // g_uimCanHandle->uim_query(&queryParam);
}

void openlid_godown_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_OPENLID,"/openlid/godown/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

int openlid_godown_act(void * dataIn)
{
    return openlid_gotoscan_act(dataIn);
}

int openlid_godown_update(void * dataIn,void * stdData)
{
    recvDataEleCtl * ptrData = (recvDataEleCtl *)dataIn;

    int * ptrFlagIn =  (int *)stdData;

    if(*ptrFlagIn==1)
    {
        return 1;
    }

    if(ptrData->sid == 10 && ptrData->frameType)
    {
        *ptrFlagIn = 1;
        return 1;
    }

    return 0;
}

void openlid_godown_query(void * dataIn)
{
    // query_param queryParam;
    // memset(&queryParam,0,sizeof(query_param));
    // queryParam.queryCode = POS;
    // queryParam.sid = 11;
    // g_uimCanHandle->uim_query(&queryParam);
}

void openlid_jawlid_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_OPENLID,"/openlid/jawlid/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

int openlid_jawlid_act(void * dataIn)
{
    int * ptrNum =  (int *)dataIn;

    printf("enter in openlid_jawlid_act\n");
    
    int num = * ptrNum;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    ctl_uim ctlFrame;
    ctlFrame.opcode = MOVE;
    ctlFrame.sid = 1;
#ifdef _GP_1
    ctlFrame.un_cmd.moveCtl.ele_index = 3;
#else
    ctlFrame.un_cmd.moveCtl.ele_index = 1;
#endif    
    ctlFrame.un_cmd.moveCtl.position = ptrParamEleCtl->position;
    ctlFrame.un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
    ctlFrame.un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
    ctlFrame.un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
    g_subBoardCanHandle->cmdAct(&ctlFrame);
    return 0;
}

int lid_operation_act(void * dataIn)
{
    int * ptrNum =  (int *)dataIn;

    printf("enter in lid_operation_act\n");
    
    int num = * ptrNum;

    if(num == 0)
    {
        return 0;
    }

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    int maxDelay = 0;
    int maxDelayI = 0;
    ctl_uim * ctlFrames = new ctl_uim[num];
    ctl_uim * ptrEleCtl = ctlFrames;
    int *sidFlagArr  = new int[num];

    int *doneFlagArr =  new int[num];

    memset(sidFlagArr,0,sizeof(int)*num);
    memset(doneFlagArr,0,sizeof(int)*num);
    printf("num is %d\n",num);
    for(int i=0;i<num;i++)
    {
       if(ptrParamEleCtl->preWait > maxDelay)
       {
           maxDelay = ptrParamEleCtl->preWait;
       }
       printf("sid from xml is %d, prewait is  %d\n",ptrParamEleCtl->sid,ptrParamEleCtl->preWait);
       if(ptrParamEleCtl->sid >= 10 && ptrParamEleCtl->sid < (MAX_UIM_CTL_NUM+10))
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = ptrParamEleCtl->sid;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 0;
       }
#ifdef _QPCR
       if(ptrParamEleCtl->sid >= 40 && ptrParamEleCtl->sid < (MAX_UIM_CTL_NUM_PCR+40))
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = ptrParamEleCtl->sid;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 0;
       }
#endif

       if(ptrParamEleCtl->sid >= 80 && ptrParamEleCtl->sid <= 83)
       {
           //here is the ele ctl on sub board
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = 1;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.ele_index = ptrParamEleCtl->sid - 80;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 1;
       }
       else if(ptrParamEleCtl->sid >= 84 && ptrParamEleCtl->sid <= 87)
       {
           //here is for the pumps and valves on system setup board
           ptrEleCtl->opcode = ptrParamEleCtl->position?CENTRE_START:CENTRE_STOP;
           ptrEleCtl->sid = 7;
           ptrEleCtl->un_cmd.djLiquidParam.chanNum = ptrParamEleCtl->sid - 84;
           ptrEleCtl->un_cmd.djLiquidParam.paramType = SYSCTL_LIQUID;
           ptrEleCtl->un_cmd.djLiquidParam.duration = 0;
           sidFlagArr[i] = 1;
       }
       else if(ptrParamEleCtl->sid >= 100 && ptrParamEleCtl->sid <= 105)
       {
           ptrEleCtl->opcode = ptrParamEleCtl->position?6:8;
           ptrEleCtl->sid = ptrParamEleCtl->sid;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           sidFlagArr[i] = 2;
       }

       ptrParamEleCtl++;
       ptrEleCtl++;
    }


    int counterDone = 0;
    int counterTime = 0;
    while(counterDone<num)
    {
        ptrEleCtl = ctlFrames;
        ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);
        for(int i=0;i<num;i++)
        {
            if(!doneFlagArr[i])
            {
                if(ptrParamEleCtl->preWait*1000 <= counterTime)
                {
                    if(sidFlagArr[i] == 1)
                    {
                        printf("subboard cmd act in lid_operation_act\n");
                        g_subBoardCanHandle->cmdAct(ptrEleCtl);
                    }
                    else if(sidFlagArr[i] == 0)
                    {
                        /* code */
                        printf("uim cmd act in lid_operation_act\n");
                        g_uimCanHandle->cmdAct(ptrEleCtl);
                    }
                    else if(sidFlagArr[i] == 2) 
                    {
                        //for wontec jaw
                        pthread_t handle;
                        pthread_create(&handle,NULL,funcDp1Jaw,ptrParamEleCtl);
                    }                   
                    
                    doneFlagArr[i] = 1;
                    counterDone++;
                }
                
            }
            ptrEleCtl++;
            ptrParamEleCtl++;
        }

        usleep(20000);
        counterTime += 20000;

        if(maxDelay*1000 < counterTime)
        {
            break;
        }
    }
    // for(int i=0;i<num;i++)
    // {
    //     printf("doneFlagArr[%d]=%d,",i,doneFlagArr[i]);
    //     if(doneFlagArr[i]==0)
    //     {
    //         printf("sidFlagArr[%d]=%d\n",i,sidFlagArr[i]);
    //     }        
    // }

    // printf("\n");

    delete [] ctlFrames;
    delete [] sidFlagArr;
    delete [] doneFlagArr;
    ctlFrames = NULL;
    sidFlagArr = NULL;
    doneFlagArr = NULL;
    return 0;
}

int dp8_move_xy(void * dataIn)
{
    int * ptrNum =  (int *)dataIn;

    printf("enter in dp8_move_xy\n");
    
    int num = * ptrNum;

    if(num == 0)
    {
        return 0;
    }

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    int maxDelay = 0;
    int maxDelayI = 0;
    ctl_uim * ctlFrames = new ctl_uim[num];
    ctl_uim * ptrEleCtl = ctlFrames;
    int *sidFlagArr  = new int[num];

    //int *doneFlagArr =  new int[num];

    memset(sidFlagArr,0,sizeof(int)*num);
    //memset(doneFlagArr,0,sizeof(int)*num);
    printf("num is %d\n",num);
    ctl_uim * ptrDp8xParam = NULL; 
    ctl_uim * ptrDp8yParam = NULL;

    int numDone = 2;

    for(int i=0;i<num;i++)
    {
       if(ptrParamEleCtl->preWait > maxDelay)
       {
           maxDelay = ptrParamEleCtl->preWait;
       }
       printf("sid from xml is %d, prewait is  %d\n",ptrParamEleCtl->sid,ptrParamEleCtl->preWait);

       if(ptrParamEleCtl->sid >= 80 && ptrParamEleCtl->sid <= 83)
       {
           //here is the ele ctl on sub board
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = 1;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.ele_index = ptrParamEleCtl->sid - 80;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 1;
           if(ptrParamEleCtl->sid == 80)
           {
               ptrDp8yParam = ptrEleCtl;
           }
           else if(ptrParamEleCtl->sid == 81)
           {
               ptrDp8xParam = ptrEleCtl;
           }
       }
       else if(ptrParamEleCtl->sid >= 10 && ptrParamEleCtl->sid < (MAX_UIM_CTL_NUM+10))
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = ptrParamEleCtl->sid;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 0;
       }

       ptrParamEleCtl++;
       ptrEleCtl++;
    }

    ptrEleCtl = ctlFrames;
    for(int i=0;i<num;i++)
    {
        if(sidFlagArr[i]==0)
        {
            g_uimCanHandle->cmdAct(ptrEleCtl);
        }
        ptrEleCtl++;
    }
    
    int currPosDp8y = eleOnBoardArr[0].currPos;
    int dstPosDp8y = ptrDp8yParam->un_cmd.moveCtl.position;

    ctl_uim * ptrParam[2] = {NULL, NULL};

    if(currPosDp8y > dstPosDp8y)
    {//y move first
       ptrParam[0] = ptrDp8yParam;
       ptrParam[1] = ptrDp8xParam;
        
    }
    else
    {//x move first
       ptrParam[0] = ptrDp8xParam;
       ptrParam[1] = ptrDp8yParam;
    }
    sleep(2);
    for(int i=0;i<2;i++)
    {
        int index_ele = ptrParam[i]->un_cmd.moveCtl.ele_index;
        g_subBoardCanHandle->cmdAct(ptrParam[i]);
        if(i<(num-1))
        {
            int count = 6000;
            while(eleOnBoardArr[index_ele].currPos!=ptrParam[i]->un_cmd.moveCtl.position)
            {
                usleep(20000);
                count--;
                if(count<0)
                {
                    break;
                }
            }

        }
        
    }
    
    // ptrEleCtl = ctlFrames;
    // for(int i=0;i<num;i++)
    // {
    //     if(sidFlagArr[i]==0)
    //     {
    //         g_uimCanHandle->cmdAct(ptrEleCtl);
    //     }
    //     ptrEleCtl++;
    // }
    

    

    delete [] ctlFrames;
    delete [] sidFlagArr;
    //delete [] doneFlagArr;
    ctlFrames = NULL;
    //sidFlagArr = NULL;
    //doneFlagArr = NULL;
    return 0;
}

int dj_pump_act(void * dataIn, int isSuckOrSpit)
{
    int * ptrNum =  (int *)dataIn;

    const int SID_DJ_PUMP = 40;

    printf("enter in dj_pump_act\n");
    
    int num = * ptrNum;

    if(num == 0)
    {
        return 0;
    }

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    int maxDelay = 0;
    int maxDelayI = 0;
    ctl_uim * ctlFrames = new ctl_uim[num];
    ctl_uim * ptrEleCtl = ctlFrames;
    int *sidFlagArr  = new int[num];

    int *doneFlagArr =  new int[num];

    memset(sidFlagArr,0,sizeof(int)*num);
    memset(doneFlagArr,0,sizeof(int)*num);
    printf("num is %d\n",num);
    for(int i=0;i<num;i++)
    {
       if(ptrParamEleCtl->preWait > maxDelay)
       {
           maxDelay = ptrParamEleCtl->preWait;
       }
       printf("sid from xml is %d, prewait is  %d\n",ptrParamEleCtl->sid,ptrParamEleCtl->preWait);

#ifdef _QPCR
       if(ptrParamEleCtl->sid >= 40 && ptrParamEleCtl->sid < (MAX_UIM_CTL_NUM_PCR+40))
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = ptrParamEleCtl->sid;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 0;
       }
#endif
       ptrParamEleCtl++;
       ptrEleCtl++;
    }


    int counterDone = 0;
    int counterTime = 0;
    while(counterDone<num)
    {
        ptrEleCtl = ctlFrames;
        ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);
        for(int i=0;i<num;i++)
        {
            if(!doneFlagArr[i])
            {
                if(ptrParamEleCtl->preWait*1000 <= counterTime)
                {
                    if(sidFlagArr[i] == 1)
                    {
                        printf("subboard cmd act in dj_pump_act\n");
                        g_subBoardCanHandle->cmdAct(ptrEleCtl);
                    }
                    else if(sidFlagArr[i] == 0)
                    {
                        /* code */
                        printf("uim cmd act in dj_pump_act,position[%d]\n",ptrEleCtl->un_cmd.moveCtl.position);
                        if(SID_DJ_PUMP==ptrEleCtl->sid)
                        {
                            move_param moveParam;
                            memset(&moveParam,0,sizeof(move_param));
                            moveParam.sid = SID_DJ_PUMP;
                            moveParam.pos = ptrEleCtl->un_cmd.moveCtl.position;
                            moveParam.dec_speed = ptrEleCtl->un_cmd.moveCtl.dec_speed;
                            moveParam.inc_speed = ptrEleCtl->un_cmd.moveCtl.inc_speed;
                            moveParam.dir = isSuckOrSpit?1-getELeCtlRetdir(SID_DJ_PUMP):getELeCtlRetdir(SID_DJ_PUMP);
                            moveParam.speed = ptrEleCtl->un_cmd.moveCtl.speed;
                            g_uimCanHandle->uim_move_relative(&moveParam);
                        }
                        else
                        {
                            g_uimCanHandle->cmdAct(ptrEleCtl);
                        }
                        
                    }                    
                    
                    doneFlagArr[i] = 1;
                    counterDone++;
                }
                
            }
            ptrEleCtl++;
            ptrParamEleCtl++;
        }

        usleep(20000);
        counterTime += 20000;

        if(maxDelay*1000 < counterTime)
        {
            break;
        }
    }
    // for(int i=0;i<num;i++)
    // {
    //     printf("doneFlagArr[%d]=%d,",i,doneFlagArr[i]);
    //     if(doneFlagArr[i]==0)
    //     {
    //         printf("sidFlagArr[%d]=%d\n",i,sidFlagArr[i]);
    //     }        
    // }

    // printf("\n");

    delete [] ctlFrames;
    delete [] sidFlagArr;
    delete [] doneFlagArr;
    ctlFrames = NULL;
    sidFlagArr = NULL;
    doneFlagArr = NULL;
    return 0;
}

int dj_pump_suck_act(void * dataIn)
{
    dj_pump_act(dataIn,1);
}

int dj_pump_spit_act(void * dataIn)
{
    dj_pump_act(dataIn,0);
}

extern CRs485 * g_ptrRs485WT;



int dp1_jaw_act(void * dataIn)
{
    int * ptrNum =  (int *)dataIn;

    const int SID_DP1_JAW = 105;

    const int WONTEC_JAW_DEVID = 5;

    printf("enter in dp1_jaw_act\n");
    
    int num = * ptrNum;

    if(num == 0)
    {
        return 0;
    }

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    
    pthread_t threadHandle;

    pthread_create(&threadHandle,NULL,funcDp1Jaw,ptrParamEleCtl);
    return 0;
}

void * funcDp1Jaw(void * paramIn)
{
    const int SID_DP1_JAW = 105;

    const int WONTEC_JAW_DEVID = 5;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(paramIn);

    wontec_msg_def paramJawCmd;

    pthread_detach(pthread_self());

    if(ptrParamEleCtl==NULL)
    {
        return NULL;
    }

    paramJawCmd.tarDev = WONTEC_JAW_DEVID;
    paramJawCmd.msgSrc = MSG_FROM_GRPC;

    if(SID_DP1_JAW == ptrParamEleCtl->sid)
    {
         if(ptrParamEleCtl->position)
         {
             paramJawCmd.funcCode = 6;
             paramJawCmd.paramLen = 1;
             paramJawCmd.paramData[0] = '1';
         }
         else
         {
             //paramJawCmd.funcCode = 8;
             paramJawCmd.funcCode = 6;
             paramJawCmd.paramLen = 1;
             paramJawCmd.paramData[0] = '2';
         }

         g_ptrRs485WT->cmdAct(&paramJawCmd);
       
    }
    return NULL;
}


extern sem_t sem_liquid_detect;

int liquid_probe_act(void * dataIn)
{
#define DP8_Z_SID 15
    int * ptrNum =  (int *)dataIn;

    printf("enter in liquid_probe_act\n");
    
    int num = * ptrNum;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    int maxDelay = 0;
    int maxDelayI = 0;
    ctl_uim * ctlFrames = new ctl_uim[num];
    ctl_uim * ptrEleCtl = ctlFrames;
    int *sidFlagArr  = new int[num];

    int *doneFlagArr =  new int[num];

    int dp8zPos = uimCtlArr[5].currPos;

    memset(sidFlagArr,0,sizeof(int)*num);
    memset(doneFlagArr,0,sizeof(int)*num);
    printf("num is %d\n",num);
    for(int i=0;i<num;i++)
    {
       if(ptrParamEleCtl->preWait > maxDelay)
       {
           maxDelay = ptrParamEleCtl->preWait;
       }
       printf("sid from xml is %d, prewait is  %d\n",ptrParamEleCtl->sid,ptrParamEleCtl->preWait);
    
       if(ptrParamEleCtl->sid >= 10 && ptrParamEleCtl->sid <= 19)
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = ptrParamEleCtl->sid;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 0;
       }
#ifdef _QPCR
       if(ptrParamEleCtl->sid >= 40 && ptrParamEleCtl->sid <= 59)
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = ptrParamEleCtl->sid;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 0;
       }
#endif

       if(ptrParamEleCtl->sid >= 80 && ptrParamEleCtl->sid <= 83)
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = 1;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.ele_index = ptrParamEleCtl->sid - 80;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 1;
       }

       ptrParamEleCtl++;
       ptrEleCtl++;
    }
    //1,start detecting while moving down
    ptrEleCtl = ctlFrames;
    for(int i=0;i<num;i++)
    {
        if(ptrEleCtl->sid == DP8_Z_SID && g_uimCanHandle)
        {
           //before moving z axis, start detecting on sub board
           dp8_lld dp8lldMsg;
           getFromShareMem(&dp8lldMsg,0);
           if(g_subBoardCanHandle)
           {
               ctl_uim tempParam;
               memset(&tempParam,0,sizeof(ctl_uim));
               tempParam.sid = 3;

               tempParam.opcode = CENTRE_CONFIG;
               tempParam.un_cmd.capCtlData.paramType = CAP_DELATA_ENV_LIQUID;
               tempParam.un_cmd.capCtlData.delta = dp8lldMsg.threshold;

               g_subBoardCanHandle->cmdAct(&tempParam);


               tempParam.opcode = CENTRE_START;
               tempParam.un_cmd.capCtlData.paramType = CAP_PROBE_LIQUID;
               tempParam.un_cmd.capCtlData.chanMask = 0x00ff;
               tempParam.un_cmd.capCtlData.chanNum = 0xff;               
               
               g_subBoardCanHandle->cmdAct(&tempParam);
           }           

           flagLiquidCheck = 0;
           g_uimCanHandle->cmdAct(ptrEleCtl);
           break; 
        }
        ptrEleCtl++;
    }
    struct timeval currTime;
    struct timespec tarTime;

    dp8zPos = dp8zPos>0?dp8zPos:0-dp8zPos;
    
    int deltaTimeMs = ptrEleCtl->un_cmd.moveCtl.position - dp8zPos;
    deltaTimeMs = deltaTimeMs>0?deltaTimeMs:0-deltaTimeMs;

    deltaTimeMs = (deltaTimeMs/ptrEleCtl->un_cmd.moveCtl.speed + 4)*1000;
    
    printf("deltaTimeMs:%d\n",deltaTimeMs);
    gettimeofday(&currTime, NULL);

    tarTime.tv_sec = currTime.tv_sec + deltaTimeMs/1000;
    tarTime.tv_nsec = currTime.tv_usec*1000;

    int waitRet = sem_timedwait(&sem_liquid_detect,&tarTime);
    
    //stop detecting liquid on sub board
    if(g_subBoardCanHandle)
    {
        ctl_uim tempParam;
        memset(&tempParam,0,sizeof(ctl_uim));
        tempParam.sid = 3;
        tempParam.opcode = CENTRE_STOP;
        tempParam.un_cmd.capCtlData.paramType = CAP_PROBE_LIQUID;
        tempParam.un_cmd.capCtlData.chanMask = 0x00ff;
        tempParam.un_cmd.capCtlData.chanNum = 0xff;
        
        g_subBoardCanHandle->cmdAct(&tempParam);
    }

    int ret = 0;
    if(waitRet==-1)
    {
        printf("no liquid is detected\n");
        //stop the dp8 z axis moving here.
        ctl_uim ctlFrame;
        ctlFrame.opcode = MOVE;
        ctlFrame.sid = DP8_Z_SID;
        ctlFrame.un_cmd.moveCtl.speed = 20000;
        ctlFrame.un_cmd.moveCtl.dec_speed = 100000;
        ctlFrame.un_cmd.moveCtl.inc_speed = 100000;
        ctlFrame.un_cmd.moveCtl.position = dp8zPos;

        if(g_uimCanHandle)
        {
           g_uimCanHandle->cmdAct(&ctlFrame); 
        }
        ret = -1;
        //dp8_lld dp8lldMsg;
        //getFromShareMem(&dp8lldMsg,1);
    }
    else
    {
        if(flagLiquidCheck==1)
        {
            printf("liquid probe success\n");
            ret = 1;

            if(g_uimCanHandle)
            {
                g_uimCanHandle->uim_stop(DP8_Z_SID); 
            }
        }
        else
        {
            printf("sem received,but flag is not correct\n");
            ctl_uim ctlFrame;
            ctlFrame.opcode = MOVE;
            ctlFrame.sid = DP8_Z_SID;
            ctlFrame.un_cmd.moveCtl.speed = 4000;
            ctlFrame.un_cmd.moveCtl.dec_speed = 4000;
            ctlFrame.un_cmd.moveCtl.inc_speed = 4000;
            ctlFrame.un_cmd.moveCtl.position = dp8zPos;

            if(g_uimCanHandle)
            {
                g_uimCanHandle->cmdAct(&ctlFrame); 
            }
            ret = -1;

            //dp8_lld dp8lldMsg;
            //getFromShareMem(&dp8lldMsg,1);
        }
        

    }

    

    delete [] ctlFrames;
    delete [] sidFlagArr;
    delete [] doneFlagArr;
    ctlFrames = NULL;
    sidFlagArr = NULL;
    doneFlagArr = NULL;

    return ret;
}

int liquid_suck_act(void * dataIn)
{
#define DP8_Z_SID 15
#define DP8_SUCK_SID 14
    int * ptrNum =  (int *)dataIn;

    printf("enter in liquid_suck_act\n");
    
    int num = * ptrNum;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    int maxDelay = 0;
    int maxDelayI = 0;
    ctl_uim * ctlFrames = new ctl_uim[num];
    ctl_uim * ptrEleCtl = ctlFrames;
    int *sidFlagArr  = new int[num];

    int *doneFlagArr =  new int[num];

    int dp8zPos = uimCtlArr[5].currPos;
    int dp8suckPos = uimCtlArr[4].currPos;

    memset(sidFlagArr,0,sizeof(int)*num);
    memset(doneFlagArr,0,sizeof(int)*num);
    printf("num is %d\n",num);
    for(int i=0;i<num;i++)
    {
       if(ptrParamEleCtl->preWait > maxDelay)
       {
           maxDelay = ptrParamEleCtl->preWait;
       }
       printf("sid from xml is %d, prewait is  %d\n",ptrParamEleCtl->sid,ptrParamEleCtl->preWait);
    
       if(ptrParamEleCtl->sid >= 10 && ptrParamEleCtl->sid <= 19)
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = ptrParamEleCtl->sid;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 0;
       }
#ifdef _QPCR
       if(ptrParamEleCtl->sid >= 40 && ptrParamEleCtl->sid <= 59)
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = ptrParamEleCtl->sid;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 0;
       }
#endif

       if(ptrParamEleCtl->sid >= 80 && ptrParamEleCtl->sid <= 83)
       {
           ptrEleCtl->opcode = MOVE;
           ptrEleCtl->sid = 1;
           ptrEleCtl->un_cmd.moveCtl.position = ptrParamEleCtl->position;
           ptrEleCtl->un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
           ptrEleCtl->un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
           ptrEleCtl->un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
           ptrEleCtl->un_cmd.moveCtl.ele_index = ptrParamEleCtl->sid - 80;
           ptrEleCtl->un_cmd.moveCtl.dir = 1;
           sidFlagArr[i] = 1;
       }

       ptrParamEleCtl++;
       ptrEleCtl++;
    }
    //1,start detecting while moving down
    ptrEleCtl = ctlFrames;
    for(int i=0;i<num;i++)
    {
        if(ptrEleCtl->sid == DP8_Z_SID && g_uimCanHandle)
        {
           int dir = 1-getELeCtlRetdir(DP8_Z_SID);
           //printf("liquid_suck_act,sid[%d],dir[%d]\n",DP8_Z_SID,dir);
           //g_uimCanHandle->uim_move(DP8_Z_SID,dir,
           //ptrEleCtl->un_cmd.moveCtl.position,getELeCtlLoopType(DP8_Z_SID));
           //g_uimCanHandle->cmdAct(ptrEleCtl);
           dp8_lld dp8lldMsg;
           getFromShareMem(&dp8lldMsg,1);

           int currPosZ = getELeCtlCurrPos(DP8_Z_SID);
           
           currPosZ = currPosZ>0?currPosZ:0-currPosZ;
           if((ptrEleCtl->un_cmd.moveCtl.position + currPosZ)>dp8lldMsg.maxPosition)
           {
              ptrEleCtl->un_cmd.moveCtl.position = dp8lldMsg.maxPosition - currPosZ;
           }
           move_param moveParamTemp;
           moveParamTemp.sid = DP8_Z_SID;
           moveParamTemp.pos = ptrEleCtl->un_cmd.moveCtl.position;
           moveParamTemp.dir = dir;
           moveParamTemp.inc_speed = ptrEleCtl->un_cmd.moveCtl.inc_speed;
           moveParamTemp.dec_speed = ptrEleCtl->un_cmd.moveCtl.dec_speed;
           moveParamTemp.speed = ptrEleCtl->un_cmd.moveCtl.speed;
           g_uimCanHandle->uim_move_relative(&moveParamTemp);
           //break; 
        }

        if(ptrEleCtl->sid == DP8_SUCK_SID && g_uimCanHandle)
        {
            int dir = getELeCtlRetdir(DP8_SUCK_SID);
            move_param moveParamTemp;
            moveParamTemp.sid = DP8_SUCK_SID;
            moveParamTemp.pos = ptrEleCtl->un_cmd.moveCtl.position;
            moveParamTemp.dir = dir;
            moveParamTemp.inc_speed = ptrEleCtl->un_cmd.moveCtl.inc_speed;
            moveParamTemp.dec_speed = ptrEleCtl->un_cmd.moveCtl.dec_speed;
            moveParamTemp.speed = ptrEleCtl->un_cmd.moveCtl.speed;
            g_uimCanHandle->uim_move_relative(&moveParamTemp);
        }
        ptrEleCtl++;
    }

    delete [] ctlFrames;
    delete [] sidFlagArr;
    delete [] doneFlagArr;
    ctlFrames = NULL;
    sidFlagArr = NULL;
    doneFlagArr = NULL;

    return 0;
}

int openlid_jawlid_update(void * dataIn,void * stdData)
{
    return 0;

    //return 0;
}

void openlid_jawlid_query(void * dataIn)
{
    // query_param queryParam;
    // memset(&queryParam,0,sizeof(query_param));
    // queryParam.queryCode = POS;
    // queryParam.sid = 11;
    // g_uimCanHandle->uim_query(&queryParam);
}

void openlid_goup_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_OPENLID,"/openlid/goup/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

int openlid_goup_act(void * dataIn)
{
    return openlid_gotoscan_act(dataIn);
}

int openlid_goup_update(void * dataIn,void * stdData)
{
    return openlid_godown_update(dataIn,stdData);

    //return 0;
}

void openlid_goup_query(void * dataIn)
{
    // query_param queryParam;
    // memset(&queryParam,0,sizeof(query_param));
    // queryParam.queryCode = POS;
    // queryParam.sid = 11;
    // g_uimCanHandle->uim_query(&queryParam);
}

void openlid_goreset_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_OPENLID,"/openlid/goreset/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void openlid_goreset_pre_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_OPENLID,"/openlid/goreset_pre/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

int openlid_goreset_act(void * dataIn)
{
    int * ptrNum =  (int *)dataIn;

    printf("enter in openlid_goreset_act\n");
    
    int num = * ptrNum;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);

    move_param  stMoveParam;
    memset(&stMoveParam,0,sizeof(move_param));

    printf("data read from xml,sid:%d,pos:%d,acc:%d,dec:%d,speed:%d\n",
    ptrParamEleCtl->sid,
    ptrParamEleCtl->position,
    ptrParamEleCtl->dec,
    ptrParamEleCtl->acc,
    ptrParamEleCtl->speed);
    stMoveParam.sid = ptrParamEleCtl->sid;
    stMoveParam.pos = ptrParamEleCtl->position;
    stMoveParam.dec_speed = ptrParamEleCtl->dec;
    stMoveParam.inc_speed = ptrParamEleCtl->acc;
    stMoveParam.speed = ptrParamEleCtl->speed;

    g_uimCanHandle->uim_ret_back(&stMoveParam);
    return 0;
}

int openlid_goreset_update(void * dataIn,void * stdData)
{
    recvDataEleCtl * ptrData = (recvDataEleCtl *)dataIn;

    int * ptrFlagIn =  (int *)stdData;

    if(*ptrFlagIn==1)
    {
        return 1;
    }

    if(ptrData->sid == 11 && ptrData->frameType == S1_EDGE)
    {
        *ptrFlagIn = 1;
        return 1;
    }

    return 0;

    //return 0;
}

void openlid_goreset_query(void * dataIn)
{
    // query_param queryParam;
    // memset(&queryParam,0,sizeof(query_param));
    // queryParam.queryCode = POS;
    // queryParam.sid = 11;
    // g_uimCanHandle->uim_query(&queryParam);
}

void closelid_goopen_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_CLOSELID,"/closelid/goto_open/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void closelid_godown_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_CLOSELID,"/closelid/godown/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void closelid_jawlid_open_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_CLOSELID,"/closelid/jawlid_open/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void closelid_goup_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_CLOSELID,"/closelid/goup/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void closelid_goreset_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_CLOSELID,"/closelid/goreset/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void closelid_goreset_pre_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_CLOSELID,"/closelid/goreset_pre/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void xrAtoB_gotoB_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_XR,"/xr/gotoB/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void xrAtoB_godown_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_XR,"/xr/godown/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void xrAtoB_jawclose_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_XR,"/xr/jawclose/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void xrAtoB_rotate_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_XR,"/xr/rotate/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void xrAtoB_jawopen_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_XR,"/xr/jawopen/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void xrAtoB_goup_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_XR,"/xr/goup/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void bash_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_BATH,"/qpcr/bash/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void trans_gotoYend_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/gotoYend/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void trans_godown_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/godown/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void trans_jawclose_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/jawclose/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void trans_goup_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/goup/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void trans_gotoYstart_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/gotoYstart/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void trans_bashgodown_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/bashgodown/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void trans_xgoend_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/xgoend/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void trans_jawopen_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/jawopen/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void trans_xgotoheat_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/xgotoheat/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void trans_bashgoup_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/bashgoup/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void trans_goreset_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/goreset/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}


void bashmove_bashgodown_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/bashgodown/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void bashmove_xgoend_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/xgoend/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void bashmove_xgotoheat_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/xgotoheat/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void bashmove_bashgoup_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_TRANS,"/qpcr/bashgoup/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

int trans_goreset_update(void * dataIn,void * stdData)
{
    recvDataEleCtl * ptrData = (recvDataEleCtl *)dataIn;

    int * ptrFlagIn =  (int *)stdData;

    if(*ptrFlagIn==1)
    {
        return 1;
    }

    if(ptrData->sid == 41 && ptrData->frameType == S1_EDGE)
    {
        *ptrFlagIn = 1;
        return 1;
    }

    return 0;

    //return 0;
}

int isAllAckFinished(void * dataToCheck)
{
   eleActCheck * ptrDataDesired =  (eleActCheck *)dataToCheck;
   int ret = 1;
   while(ptrDataDesired!=NULL)
   {
       if(ptrDataDesired->status == 0)
       {
           ret = 0;
           break;
       }
       ptrDataDesired = ptrDataDesired->next;
   }

   return ret;
}

int check_update(void * dataIn,void * stdData)
{
    recvDataEleCtl * ptrData = (recvDataEleCtl *)dataIn;
    eleActCheck * dataDesired = (eleActCheck *)stdData;
    eleActCheck * ptrDataDesired = dataDesired;

    
    int ret = 1;
    if(dataIn==NULL || stdData==NULL)
    {
        return 0;
    }
    while(ptrDataDesired!=NULL)
    {
        if( ptrDataDesired->valueDesired.sid != ptrData->sid)
        {
            if(ptrDataDesired->status == 0)
            {
               //printf("check_update set ret to 0,111\n");
               ret = 0;
            }            
        }
        else //if(ptrDataDesired->valueDesired.sid == ptrData->sid)
        {
            if(ptrDataDesired->valueDesired.frameType == ptrData->frameType)
            {
               //printf("check_update set status to 1, sid[%d]\n",ptrData->sid);
               ptrDataDesired->status = 1;
            }
            
            if(ptrDataDesired->status == 0)
            {
                //printf("check_update set ret to 0,222\n");
                ret = 0;
            }
        }
        ptrDataDesired=ptrDataDesired->next;
    }
    //printf("check_update ret:%d\n",ret);
    return ret;
}

void set_check_data(void * dataIn,void ** dataOut)
{
    int * ptrNum =  (int *)dataIn;

    printf("enter in set_check_data\n");
    if(ptrNum==NULL)
    {
        *dataOut = NULL;
        return;
    }
    
    int num = * ptrNum;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNum+1);
    

    eleActCheck * checkData = new eleActCheck[num];
    memset(checkData,0,sizeof(eleActCheck)*num);

    eleActCheck * ptrCheckData = checkData;

    for(int i=0;i<num;i++)
    {
        ptrCheckData->valueDesired.sid = ptrParamEleCtl->sid;

        if(ptrParamEleCtl->sid>=84 && ptrParamEleCtl->sid <= 87)
        {
            //for pump and valves of dj
            ptrCheckData->valueDesired.frameType = CHECK_MOVE_END;
        }
        else if(ptrParamEleCtl->sid>=100 && ptrParamEleCtl->sid <= 105)
        {
            //for wantec ele controller
            ptrCheckData->valueDesired.frameType = CHECK_MOVE_END;
        }
        else
        {
            if(ptrParamEleCtl->position == 0)
            {
                ptrCheckData->valueDesired.frameType = CHECK_RET_BACK_END;
            }
            else
            {
                ptrCheckData->valueDesired.frameType = CHECK_MOVE_END;
            }
        }     

        if(i<(num-1))
        {
            ptrCheckData->next = ptrCheckData+1;
        }

        ptrCheckData++;      
        ptrParamEleCtl++;
    }

    *dataOut = checkData;
}

void dp8_zret_read_param(void * dataOut,void * dataIn)
{ 
#if _USE_XML_ 
    pthread_mutex_lock(&mutex_read_param);  
    read_param_xml(I_FILE_DP8,"/dp8/z_ret/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_FILE_DP8,"dp8.z_ret.electl",dataOut,NULL);
#endif
}

void dp8_loc_horizen_read_param(void * dataOut,void * dataIn)
{ 
#if _USE_XML_ 
    pthread_mutex_lock(&mutex_read_param);  
    read_param_xml(I_FILE_DP8,"/dp8/loc_horizen/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_FILE_DP8,"dp8.loc_horizen.electl",dataOut,NULL);
#endif
}

void dp8_loc_vertical_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_FILE_DP8,"/dp8/loc_vertical/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_FILE_DP8,"dp8.loc_vertical.electl",dataOut,NULL);
#endif
}

void dp8_probe_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP8SUCK,"/dp8/probe/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_MODULE_DP8SUCK,"dp8.probe.electl",dataOut,NULL);
#endif
}

void dp8_suckact_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP8SUCK,"/dp8/suck_act/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_MODULE_DP8SUCK,"dp8.suck_act.electl",dataOut,NULL);
#endif
}

void dp8_suckend_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP8SUCK,"/dp8/suck_end/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_MODULE_DP8SUCK,"dp8.suck_end.electl",dataOut,NULL);
#endif
}

void dp8_droptip_down_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP8DROPTIP,"/dp8/droptip_down/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_MODULE_DP8DROPTIP,"dp8.droptip_down.electl",dataOut,NULL);
#endif
}
void dp8_droptip_up_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP8DROPTIP,"/dp8/droptip_up/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_MODULE_DP8DROPTIP,"dp8.droptip_up.electl",dataOut,NULL);
#endif
}

void dp8_split_down_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP8SPIT,"/dp8/spit_down/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_MODULE_DP8SPIT,"dp8.spit_down.electl",dataOut,NULL);
#endif
}
void dp8_split_up_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP8SPIT,"/dp8/spit_up/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_MODULE_DP8SPIT,"dp8.spit_up.electl",dataOut,NULL);
#endif
}

void dp8_ontip_down_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP8ONTIP,"/dp8/ontip_down/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_MODULE_DP8ONTIP,"dp8.ontip_down.electl",dataOut,NULL);
#endif
}
void dp8_ontip_up_read_param(void * dataOut,void * dataIn)
{
#if _USE_XML_
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP8ONTIP,"/dp8/ontip_up/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
#else
    read_param_json(I_MODULE_DP8ONTIP,"dp8.ontip_up.electl",dataOut,NULL);
#endif
}

void bashzmove_read_param(void * dataOut,void * dataIn)
{
    paramProcNode * ptrProcParam = (paramProcNode *)dataOut;
    int * tempPtr = (int*)dataOut;
    paramEleCtl * ptrParamEleCtl = (paramEleCtl *) (tempPtr+1);

    move_param * ptrParamIn =  (move_param *)dataIn;

    const int num_ele_ctl = 2;
    const int sidArr[2] = {45,46};

    for(int i=0;i<num_ele_ctl;i++)
    {
        ptrParamEleCtl->sid = sidArr[i];
        ptrParamEleCtl->speed = ptrParamIn->speed;
        ptrParamEleCtl->acc = ptrParamIn->inc_speed;
        ptrParamEleCtl->dec = ptrParamIn->dec_speed;
        ptrParamEleCtl->position = ptrParamIn->pos;


        ptrParamEleCtl++;
    }

    *tempPtr = num_ele_ctl;    
}

void bash1zmove_read_param(void * dataOut,void * dataIn)
{
    paramProcNode * ptrProcParam = (paramProcNode *)dataOut;
    int * tempPtr = (int*)dataOut;
    paramEleCtl * ptrParamEleCtl = (paramEleCtl *) (tempPtr+1);

    move_param * ptrParamIn =  (move_param *)dataIn;

    const int num_ele_ctl = 2;
    const int sidArr[2] = {52,53};

    for(int i=0;i<num_ele_ctl;i++)
    {
        ptrParamEleCtl->sid = sidArr[i];
        ptrParamEleCtl->speed = ptrParamIn->speed;
        ptrParamEleCtl->acc = ptrParamIn->inc_speed;
        ptrParamEleCtl->dec = ptrParamIn->dec_speed;
        ptrParamEleCtl->position = ptrParamIn->pos;


        ptrParamEleCtl++;
    }

    *tempPtr = num_ele_ctl;    
}

void djreagnet_reset0_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DJREAGENT,"/dj/reset0/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void djreagnet_gotoreagent_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DJREAGENT,"/dj/gotoreagent/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void djreagnet_suck_air_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DJREAGENT,"/dj/suck_air/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void djreagnet_zgodown_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);    
    read_param_xml(I_MODULE_DJREAGENT,"/dj/zgodown/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void djreagnet_suck_reagent_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DJREAGENT,"/dj/suck_reagent/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void djreagnet_spit_reagent_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);    
    read_param_xml(I_MODULE_DJREAGENT,"/dj/spit_reagent/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void djreagnet_zreset_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DJREAGENT,"/dj/zreset/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void transtube_jawzret_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP1TRANSTUBE,"/translid/jawzret/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void transtube_changePos(void * paramAll, tube_trans * paramCtl,  int isSrc)
{
    int * tempPtr = (int*)paramAll;
    paramEleCtl * ptrParamEleCtl = (paramEleCtl *) (tempPtr+1);

    const int SID_DP1_X = 20;
    const int SID_DP1_Y = 21;
    const int SID_DP1_JAWZ = 22;
    
    for(int i=0;i<(*tempPtr);i++)
    {
        if(ptrParamEleCtl->sid == SID_DP1_X)
        {
            ptrParamEleCtl->position = isSrc?paramCtl->Xsrc:paramCtl->Xtar;
        }
        else if(ptrParamEleCtl->sid == SID_DP1_Y)
        {
            ptrParamEleCtl->position = isSrc?paramCtl->Ysrc:paramCtl->Ytar;
        }
        else if(ptrParamEleCtl->sid == SID_DP1_JAWZ)
        {
            ptrParamEleCtl->position = isSrc?paramCtl->Zsrc:paramCtl->Ztar;
        }

        ptrParamEleCtl++;
    }
    
}

void transtube_gotosrc_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP1TRANSTUBE,"/translid/gotosrc/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);    
    
    transtube_changePos(dataOut,(tube_trans *)dataIn,1);
}
void transtube_jawzdown1_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP1TRANSTUBE,"/translid/jawzdown1/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
    transtube_changePos(dataOut,(tube_trans *)dataIn,1);
}
void transtube_dp1jawclose_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
	read_param_xml(I_MODULE_DP1TRANSTUBE,"/translid/dp1jawclose/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void transtube_jawzup1_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP1TRANSTUBE,"/translid/jawzup1/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void transtube_gototar_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP1TRANSTUBE,"/translid/gototar/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
    transtube_changePos(dataOut,(tube_trans *)dataIn,0);
}
void transtube_jawzdown2_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP1TRANSTUBE,"/translid/jawzdown2/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
    transtube_changePos(dataOut,(tube_trans *)dataIn,0);
}
void transtube_dp1jawopen_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP1TRANSTUBE,"/translid/dp1jawopen/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}
void transtube_jawzup2_read_param(void * dataOut,void * dataIn)
{
    pthread_mutex_lock(&mutex_read_param);
    read_param_xml(I_MODULE_DP1TRANSTUBE,"/translid/jawzup2/electl",dataOut);
    pthread_mutex_unlock(&mutex_read_param);
}

void * dp8_lld_threadfunc(void * dataIn)
{
    pthread_detach(pthread_self());
    
    const int sid_dp8_z = 15;

    dp8_lld * ptrDp8lldParam = (dp8_lld *)dataIn;

    if(g_subBoardCanHandle)
    {
        ctl_uim tempParam;
        memset(&tempParam,0,sizeof(ctl_uim));

        tempParam.sid = 3;
        tempParam.opcode = CENTRE_CONFIG;
        tempParam.un_cmd.capCtlData.paramType = CAP_DELATA_ENV_LIQUID;
        tempParam.un_cmd.capCtlData.delta = ptrDp8lldParam->threshold;

        g_subBoardCanHandle->cmdAct(&tempParam);


        tempParam.opcode = CENTRE_START;
        tempParam.un_cmd.capCtlData.paramType = CAP_PROBE_LIQUID;
        tempParam.un_cmd.capCtlData.chanMask = 0x00ff;
        tempParam.un_cmd.capCtlData.chanNum = 0xff;

        g_subBoardCanHandle->cmdAct(&tempParam);
    }
    
    

    flagLiquidCheck = 0;
    if(g_uimCanHandle)
    {
        ctl_uim eleCtl;
        memset(&eleCtl,0,sizeof(ctl_uim));

        eleCtl.sid = sid_dp8_z;
        eleCtl.opcode = MOVE;
        eleCtl.un_cmd.moveCtl.dec_speed = ptrDp8lldParam->dec;
        eleCtl.un_cmd.moveCtl.inc_speed = ptrDp8lldParam->acc;
        eleCtl.un_cmd.moveCtl.speed = ptrDp8lldParam->speed;
        eleCtl.un_cmd.moveCtl.position = ptrDp8lldParam->maxPosition;
        g_uimCanHandle->cmdAct(&eleCtl);
    }


    struct timeval currTime;
    struct timespec tarTime;

    int dp8zPos = getELeCtlCurrPos(sid_dp8_z);
    dp8zPos = dp8zPos>0?dp8zPos:0-dp8zPos;
    
    int deltaTimeMs = ptrDp8lldParam->maxPosition - dp8zPos;
    deltaTimeMs = deltaTimeMs>0?deltaTimeMs:0-deltaTimeMs;

    deltaTimeMs = (deltaTimeMs/ptrDp8lldParam->speed + 4)*1000;
    
    printf("deltaTimeMs:%d\n",deltaTimeMs);
    gettimeofday(&currTime, NULL);

    tarTime.tv_sec = currTime.tv_sec + deltaTimeMs/1000;
    tarTime.tv_nsec = currTime.tv_usec*1000;

    int waitRet = sem_timedwait(&sem_liquid_detect,&tarTime);
    
    //stop detecting liquid on sub board
    if(g_subBoardCanHandle)
    {
        ctl_uim tempParam;
        memset(&tempParam,0,sizeof(ctl_uim));
        tempParam.sid = 3;
        tempParam.opcode = CENTRE_STOP;
        tempParam.un_cmd.capCtlData.paramType = CAP_PROBE_LIQUID;
        tempParam.un_cmd.capCtlData.chanMask = 0x00ff;
        tempParam.un_cmd.capCtlData.chanNum = 0xff;
        
        g_subBoardCanHandle->cmdAct(&tempParam);
    }

    int ret = 0;
    if(waitRet==-1)
    {
        printf("no liquid is detected\n");
        //stop the dp8 z axis moving here.
        ctl_uim ctlFrame;
        ctlFrame.opcode = MOVE;
        ctlFrame.sid = DP8_Z_SID;
        ctlFrame.un_cmd.moveCtl.speed = 20000;
        ctlFrame.un_cmd.moveCtl.dec_speed = 100000;
        ctlFrame.un_cmd.moveCtl.inc_speed = 100000;
        ctlFrame.un_cmd.moveCtl.position = dp8zPos;

        if(g_uimCanHandle)
        {
           g_uimCanHandle->cmdAct(&ctlFrame); 
        }
        ret = -1;
    }
    else
    {
        if(flagLiquidCheck==1)
        {
            printf("liquid probe success\n");
            ret = 1;

            if(g_uimCanHandle)
            {
                g_uimCanHandle->uim_stop(DP8_Z_SID); 
            }
        }
        else
        {
            printf("sem received,but flag is not correct\n");
            ctl_uim ctlFrame;
            ctlFrame.opcode = MOVE;
            ctlFrame.sid = DP8_Z_SID;
            ctlFrame.un_cmd.moveCtl.speed = 4000;
            ctlFrame.un_cmd.moveCtl.dec_speed = 4000;
            ctlFrame.un_cmd.moveCtl.inc_speed = 4000;
            ctlFrame.un_cmd.moveCtl.position = dp8zPos;

            if(g_uimCanHandle)
            {
                g_uimCanHandle->cmdAct(&ctlFrame); 
            }
            ret = -1;
        }
        

    }

    if(ret==1)
    {
       //detecting success
       //send msg to grpc
       sendAckToGrpc(0,0,0, I_MODULE_DP8LLD);
    }
    else
    {
       //detecting failed
       //send msg to grpc
       sendAckToGrpc(2,4,0, I_MODULE_DP8LLD);
    }


    delete ptrDp8lldParam;
}

FILE * g_fp_z = NULL;

#define DP8Z_DATA_FILE "/mnt/nandflash/apps/z_pos"

pthread_mutex_t mutexWriteDp8Z = PTHREAD_MUTEX_INITIALIZER;

void * funcSampleCap(void * paramIn )
{
    dp8capSample * ptrSampleParam = (dp8capSample *)paramIn;
    printf("enter in funcSampleCap\n");

    pthread_detach(pthread_self());

    char buffStep1[256];
    char buffStep2[256];

    memset(buffStep1,0,256);
    memset(buffStep2,0,256);

    read_param_json(I_MODULE_DP8SUCK_AB,"dp8.z_godown.electl",buffStep1,NULL);
    read_param_json(I_MODULE_DP8SUCK_AB,"dp8.z_goup.electl",buffStep2,NULL);
    
    int * ptrNumParam = (int *)buffStep1;
    int i = 0;

    paramEleCtl * ptrParamEleCtl = (paramEleCtl *)(ptrNumParam+1);

    ctl_uim eleCtlParamZDown;
    memset(&eleCtlParamZDown,0,sizeof(ctl_uim));

    move_param eleCtlParamSuck;
    memset(&eleCtlParamSuck,0,sizeof(move_param));
    
    ctl_uim eleCtlParamZUp;
    memset(&eleCtlParamZUp,0,sizeof(ctl_uim));

    for(i=0;i<(* ptrNumParam);i++)
    {
        if(ptrParamEleCtl->sid == 15)
        {
            eleCtlParamZDown.sid = 15;
            eleCtlParamZDown.opcode = MOVE;
            eleCtlParamZDown.un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
            eleCtlParamZDown.un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
            eleCtlParamZDown.un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
            eleCtlParamZDown.un_cmd.moveCtl.position = ptrParamEleCtl->position;
        }
        else if(ptrParamEleCtl->sid == 14)
        {
            eleCtlParamSuck.sid = 14;
            eleCtlParamSuck.dir = getELeCtlRetdir(14);
            eleCtlParamSuck.dec_speed = ptrParamEleCtl->dec;
            eleCtlParamSuck.inc_speed = ptrParamEleCtl->acc;
            eleCtlParamSuck.speed = ptrParamEleCtl->speed;
            eleCtlParamSuck.pos = ptrParamEleCtl->position;
        }
       ptrParamEleCtl++;    
    }


    ptrNumParam = (int *)buffStep2;
    ptrParamEleCtl = (paramEleCtl *)(ptrNumParam+1);
    for(i=0;i<(* ptrNumParam);i++)
    {
        if(ptrParamEleCtl->sid == 15)
        {
            eleCtlParamZUp.sid = 15;
            eleCtlParamZUp.opcode = MOVE;
            eleCtlParamZUp.un_cmd.moveCtl.dec_speed = ptrParamEleCtl->dec;
            eleCtlParamZUp.un_cmd.moveCtl.inc_speed = ptrParamEleCtl->acc;
            eleCtlParamZUp.un_cmd.moveCtl.speed = ptrParamEleCtl->speed;
            eleCtlParamZUp.un_cmd.moveCtl.position = ptrParamEleCtl->position;
        }

        ptrParamEleCtl++;    
    }



    if(g_uimCanHandle==NULL)
    {
        printf("g_uimCanHandle is NULL\n");
        return NULL;
    }

    if(ptrSampleParam==NULL)
    {
        printf("param ptrEleCtl is NULL\n");
        return NULL;
    }

    int tarPos = ptrSampleParam->position;

    tarPos = (tarPos>0)?tarPos:0-tarPos;
    

    int currPos = getELeCtlCurrPos(15);

    currPos = currPos>0?currPos:0-currPos;

    int delta = currPos>tarPos?(currPos - tarPos):(tarPos - currPos);

    query_param queryParam;
    memset(&queryParam,0,sizeof(query_param));
    queryParam.queryCode = POS;
    queryParam.sid = 15;

    int interv_mm = ptrSampleParam->interval;
    if(interv_mm>10)
    {
       interv_mm -= 5; 
    }

    int maxCnt = 180000/interv_mm;


    sample_queue_msg ctlFrame;

    memset(&ctlFrame,0,sizeof(sample_queue_msg));
    ctlFrame.type = QUEUE_MSG_TYPE_SAMPLE;
    ctlFrame.sampleMsg.act_type = START_SAMPLE;
    ctlFrame.sampleMsg.boardId = 3;
    ctlFrame.sampleMsg.chan = ptrSampleParam->chanMask;
    ctlFrame.sampleMsg.data_type = CAPACITY_SAMPLE;

    
    if(msgsnd(g_uimCanHandle->getKeyId_FrameMQ(), (void*)&ctlFrame, sizeof(sample_msg), 0) < 0)
    {
       printf("send msg to start sample failed\n");
    }

    struct timeval tv;
    gettimeofday(&tv,NULL);

    if(g_fp_z==NULL)
    {
        char buffFileName[256] = {0};
        sprintf(buffFileName,"%s_%d.txt",DP8Z_DATA_FILE,tv.tv_sec);
        g_fp_z = fopen(buffFileName,"w+");
    }

    g_uimCanHandle->cmdAct(&eleCtlParamZDown);   

    while(currPos<ptrSampleParam->position)
    {
        if(g_uimCanHandle)
        {
           g_uimCanHandle->uim_query(&queryParam);
        }
         
        usleep(interv_mm*1000);        

        currPos = getELeCtlCurrPos(15);
        currPos = currPos>0?currPos:0-currPos;

        maxCnt--;
        if(maxCnt<=0)
        {
            break;
        }
    }
    g_uimCanHandle->uim_move_relative(&eleCtlParamSuck);
    
    char statusMove = 0;

    maxCnt = 120000/interv_mm;
    while(1)
    {
        if(g_uimCanHandle)
        {
           g_uimCanHandle->uim_query(&queryParam);
        }
        usleep(interv_mm*1000);
        if(getELeCtlStatus(14)==5)
        {
            statusMove = statusMove|0x01;
        }

        if(getELeCtlStatus(15)==5)
        {
            statusMove = statusMove|0x02;
        }

        if(statusMove==0x03)
        {
            break;
        }
        else 
        {
            if(maxCnt%100 == 99)
            {
                printf("status14:%d,status15:%d,statusMove:%02x\n",
            getELeCtlStatus(14),
            getELeCtlStatus(15),
            statusMove);

            }
            
        }

        maxCnt--;

        if(maxCnt<=0)
        {
            break;
        }

    } 

    g_uimCanHandle->cmdAct(&eleCtlParamZUp);
    //maxCnt = 600;
    maxCnt = 120000/interv_mm;
    while(1)
    {
        if(g_uimCanHandle)
        {
           g_uimCanHandle->uim_query(&queryParam);
        }
        usleep(interv_mm*1000);
        
        int dstPos = eleCtlParamZUp.un_cmd.moveCtl.position;
        dstPos = dstPos>0?dstPos:(0-dstPos);

        currPos = getELeCtlCurrPos(15);
        currPos = currPos>0?currPos:(0-currPos);

        int delta = currPos>dstPos?(currPos-dstPos):(dstPos-currPos);
        if(delta<8)//if(getELeCtlStatus(15)==5 || delta<8)
        {
            printf("dp8 z move end,do not query pos from now\n");
            break;
        }
        else 
        {
            if(maxCnt%100 == 99)
            {
                printf("status15:%d\n", getELeCtlStatus(15));

            }
            
        }
        

        maxCnt--;

        if(maxCnt<=0)
        {
            break;
        }

    }

    ctlFrame.type = QUEUE_MSG_TYPE_SAMPLE;
    ctlFrame.sampleMsg.act_type = STOP_SAMPLE;
    ctlFrame.sampleMsg.boardId = 3;
    ctlFrame.sampleMsg.chan = 0xff;
    ctlFrame.sampleMsg.data_type = CAPACITY_SAMPLE; 

    
    if(msgsnd(g_uimCanHandle->getKeyId_FrameMQ(), (void*)&ctlFrame, sizeof(sample_msg), 0) < 0)
    {
       printf("send msg to stop sample failed\n");
    }
    
    
    delete ptrSampleParam;
    pthread_mutex_lock(&mutexWriteDp8Z);
    if(g_fp_z)
    {
        fclose(g_fp_z);
        g_fp_z = NULL;
    }
    pthread_mutex_unlock(&mutexWriteDp8Z);

    sendAckToGrpc(0,0,0, I_MODULE_DP8SAMPLE);     
}